{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#  Convolutional Neural Network\n",
    "\n",
    "### Convolutional Layers: [128,128,128] ; Dense Layers [128,128,128] \n",
    "### CNN regularized with l2 regularization in dense layers\n",
    "\n",
    "CNN is trained on raw data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Get the data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Stored variables and their in-db values:\n",
      "X_test              -> defaultdict(<class 'list'>, {0: array([[[-0.000654\n",
      "X_train             -> array([[[-0.00107939, -0.00131855, -0.00122601, ..\n",
      "snrs                -> [-20, -18, -16, -14, -12, -10, -8, -6, -4, -2, 0, \n",
      "y_test              -> defaultdict(<class 'list'>, {0: array([5, 5, 5, ..\n",
      "y_train             -> array([4, 6, 7, ..., 2, 7, 4])\n"
     ]
    }
   ],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from collections import defaultdict\n",
    "from time import time\n",
    "from functools import partial\n",
    "\n",
    "%store -r\n",
    "%store"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training data:  (80000, 2, 128) and labels:  (80000,)\n",
      "\n",
      "Test data:\n",
      "Total 20 (4000, 2, 128) arrays for SNR values:\n",
      "[-20, -18, -16, -14, -12, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18]\n"
     ]
    }
   ],
   "source": [
    "print(\"Training data: \", X_train.shape, \"and labels: \", y_train.shape)\n",
    "print()\n",
    "print(\"Test data:\")\n",
    "print(\"Total\", len(X_test), X_test[18].shape, \"arrays for SNR values:\")\n",
    "print(sorted(X_test.keys()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Standardize the features"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training set (80000, 2, 128)\n",
      "Test set corresponding to one snr value (4000, 2, 128)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "sc = StandardScaler()\n",
    "_X_train = np.reshape(X_train, [X_train.shape[0], X_train.shape[1]*X_train.shape[2]])\n",
    "_X_train = sc.fit_transform(_X_train)\n",
    "\n",
    "X_train = np.reshape(_X_train, X_train.shape)\n",
    "print(\"Training set\", X_train.shape)\n",
    "\n",
    "_X_test = defaultdict(list)\n",
    "for snr in snrs:\n",
    "    _X_test[snr] = np.reshape(X_test[snr], [X_test[snr].shape[0], X_test[snr].shape[1]*X_test[snr].shape[2]])\n",
    "    _X_test[snr] = sc.transform(_X_test[snr])\n",
    "    X_test[snr] = np.reshape(_X_test[snr], X_test[snr].shape)\n",
    "    \n",
    "print(\"Test set corresponding to one snr value\", X_test[18].shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Design and train the CNN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 0 training accuracy : 0.232421875\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l2.2\n",
      "Epoch 1 training accuracy : 0.3505859375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l2.2\n",
      "Epoch 2 training accuracy : 0.40234375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l2.2\n",
      "Epoch 3 training accuracy : 0.4560546875\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l2.2\n",
      "Epoch 4 training accuracy : 0.55859375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l2.2\n",
      "Epoch 5 training accuracy : 0.5595703125\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l2.2\n",
      "Epoch 6 training accuracy : 0.6025390625\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l2.2\n",
      "Epoch 7 training accuracy : 0.6015625\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l2.2\n",
      "Epoch 8 training accuracy : 0.595703125\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l2.2\n",
      "Epoch 9 training accuracy : 0.6103515625\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l2.2\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l2.2\n",
      "Training took 38.138862 minutes\n"
     ]
    }
   ],
   "source": [
    "height = 2\n",
    "width = 128\n",
    "channels = 1\n",
    "n_features = height * width\n",
    "\n",
    "feature_map1 = 128\n",
    "ksize_conv1 = 2\n",
    "stride_conv1 = 1\n",
    "\n",
    "feature_map2 = 128\n",
    "ksize_conv2 = ksize_conv1\n",
    "stride_conv2 = stride_conv1\n",
    "\n",
    "feature_map3 = 128\n",
    "ksize_conv3 = ksize_conv1\n",
    "stride_conv3 = stride_conv1\n",
    "\n",
    "pool_layer_maps = 128\n",
    "\n",
    "n_fully_conn1 = 128\n",
    "n_fully_conn2 = 128\n",
    "n_fully_conn3 = 128\n",
    "\n",
    "n_classes = 8\n",
    "  \n",
    "X = tf.placeholder(tf.float32, shape=[None, height, width])\n",
    "X_reshaped = tf.reshape(X, shape=[-1, height, width, channels])\n",
    "labels = tf.placeholder(tf.int32, shape=[None])\n",
    "\n",
    "weight_init = tf.contrib.layers.xavier_initializer()\n",
    "activation_func = tf.nn.relu\n",
    "\n",
    "# ------------------ Convolutional and pooling layers ----------------------------\n",
    "\n",
    "def convolutional_layer(X, filter_, ksize, kernel_init, strides, padding):\n",
    "    convolutional_layer = tf.layers.conv2d(X, filters = filter_, kernel_initializer = kernel_init,\n",
    "                                           kernel_size = ksize, strides = strides,\n",
    "                                          padding = padding, activation = activation_func)\n",
    "    return convolutional_layer\n",
    "\n",
    "def pool_layer(convlayer, ksize, strides, padding, pool_maps):\n",
    "    pool = tf.nn.max_pool(convlayer, ksize, strides, padding)\n",
    "    dim1, dim2 = int(pool.get_shape()[1]), int(pool.get_shape()[2])\n",
    "    pool_flat = tf.reshape(pool, shape = [-1, pool_maps * dim1 * dim2])\n",
    "    return pool_flat\n",
    "\n",
    "conv_layer1 = convolutional_layer(X_reshaped, feature_map1, ksize_conv1, weight_init, stride_conv1, padding = \"SAME\")\n",
    "\n",
    "conv_layer2 = convolutional_layer(conv_layer1, feature_map2, ksize_conv2, weight_init, stride_conv2, padding = \"SAME\")\n",
    "\n",
    "conv_layer3 = convolutional_layer(conv_layer2, feature_map3, ksize_conv3, weight_init, stride_conv3, padding = \"SAME\")\n",
    "\n",
    "pool_layer_flat = pool_layer(conv_layer3, [1,2,2,1], [1,2,2,1], \"VALID\", pool_layer_maps)\n",
    "\n",
    "# ----------------- Fully connected layers -------------------\n",
    "\n",
    "scale_val = 0.001\n",
    "new_dense_layer = partial(tf.layers.dense, kernel_initializer = weight_init,\n",
    "                          kernel_regularizer = tf.contrib.layers.l2_regularizer(scale_val), \n",
    "                          activation = activation_func)\n",
    "\n",
    "dense_layer1 = new_dense_layer(pool_layer_flat, n_fully_conn1)\n",
    "\n",
    "dense_layer2 = new_dense_layer(dense_layer1, n_fully_conn2)\n",
    "\n",
    "dense_layer3 = new_dense_layer(dense_layer2, n_fully_conn3)\n",
    "\n",
    "# ----------------- Output softmax layer ---------------------------\n",
    "\n",
    "logits = tf.layers.dense(dense_layer3, n_classes)\n",
    "softmax_activations = tf.nn.softmax(logits)\n",
    "\n",
    "# ----------------- Specify performance measure -------------------------------\n",
    "\n",
    "cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits = logits, labels = labels)\n",
    "\n",
    "loss = tf.reduce_mean(cross_entropy)\n",
    "regularization_loss = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)\n",
    "total_loss = tf.add_n([loss] + regularization_loss)\n",
    "\n",
    "optimizer = tf.train.AdamOptimizer()\n",
    "train_operation = optimizer.minimize(total_loss)\n",
    "\n",
    "correct_predictions = tf.nn.in_top_k(logits, labels, 1)\n",
    "accuracy = tf.reduce_mean(tf.cast(correct_predictions, tf.float32))\n",
    "\n",
    "# ---------------- Execution phase -------------------------------------------\n",
    "    \n",
    "n_epochs = 10\n",
    "batch_size = 1024\n",
    "n_train = X_train.shape[0]\n",
    "n_iter = n_train//batch_size\n",
    "\n",
    "acc_test = defaultdict(list)\n",
    "\n",
    "path = \"./CNN_regtech_l2.2\"  \n",
    "saver = tf.train.Saver()\n",
    "\n",
    "start = time()\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    tf.global_variables_initializer().run()\n",
    "    for epoch in range(n_epochs):\n",
    "        for iteration in range(n_iter):\n",
    "            rand_indices = np.random.choice(n_train,batch_size)    \n",
    "            X_batch, y_batch = X_train[rand_indices], y_train[rand_indices]\n",
    "            sess.run(train_operation, feed_dict={X: X_batch, labels: y_batch})\n",
    "        acc_train = accuracy.eval(feed_dict={X: X_batch, labels: y_batch})\n",
    "        print(\"Epoch {} training accuracy : {}\".format(epoch, acc_train))\n",
    "        save_path = saver.save(sess, path)\n",
    "        saver.restore(sess, path)\n",
    "    saver.restore(sess, path)\n",
    "    for snr in snrs:\n",
    "        acc_test[snr] = accuracy.eval(feed_dict={X: X_test[snr], labels: y_test[snr]})\n",
    "\n",
    "print(\"Training took %f minutes\"%(float(time() - start)/60.0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Test the classifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CNN's test accuracy on -20dB SNR samples = 0.12600000202655792\n",
      "CNN's test accuracy on -18dB SNR samples = 0.12250000238418579\n",
      "CNN's test accuracy on -16dB SNR samples = 0.1379999965429306\n",
      "CNN's test accuracy on -14dB SNR samples = 0.14949999749660492\n",
      "CNN's test accuracy on -12dB SNR samples = 0.19325000047683716\n",
      "CNN's test accuracy on -10dB SNR samples = 0.22425000369548798\n",
      "CNN's test accuracy on -8dB SNR samples = 0.29875001311302185\n",
      "CNN's test accuracy on -6dB SNR samples = 0.3865000009536743\n",
      "CNN's test accuracy on -4dB SNR samples = 0.5142499804496765\n",
      "CNN's test accuracy on -2dB SNR samples = 0.6642500162124634\n",
      "CNN's test accuracy on 0dB SNR samples = 0.7582499980926514\n",
      "CNN's test accuracy on 2dB SNR samples = 0.7879999876022339\n",
      "CNN's test accuracy on 4dB SNR samples = 0.8057500123977661\n",
      "CNN's test accuracy on 6dB SNR samples = 0.8084999918937683\n",
      "CNN's test accuracy on 8dB SNR samples = 0.8100000023841858\n",
      "CNN's test accuracy on 10dB SNR samples = 0.8190000057220459\n",
      "CNN's test accuracy on 12dB SNR samples = 0.8130000233650208\n",
      "CNN's test accuracy on 14dB SNR samples = 0.8040000200271606\n",
      "CNN's test accuracy on 16dB SNR samples = 0.8050000071525574\n",
      "CNN's test accuracy on 18dB SNR samples = 0.8109999895095825\n"
     ]
    }
   ],
   "source": [
    "for snr in snrs:\n",
    "    print(\"CNN's test accuracy on {}dB SNR samples = {}\".format(snr,acc_test[snr]))  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Visualize classifier's performance on test set"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nY2ZmZmZ99HdYCpbrHSE+wQAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fa2a61a3390>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.style.use('classic')\n",
    "%matplotlib inline\n",
    "\n",
    "acc_test = sorted(acc_test.items())\n",
    "new_acc = []\n",
    "for i in range(len(acc_test)):\n",
    "    new_acc.append(acc_test[i][1])\n",
    "acc_test_values = new_acc \n",
    "\n",
    "fig1 = plt.figure(figsize=(10, 6), dpi=100)\n",
    "x = snrs\n",
    "y = list(acc_test_values)\n",
    "plt.plot(x, y, marker=\"o\", linewidth=2.0, linestyle='dashed', color='royalblue')\n",
    "plt.axis([-20, 20, 0, 1])\n",
    "plt.xticks(np.arange(min(x), max(x)+1, 2.0))\n",
    "plt.yticks(np.arange(0, 1, 0.10))\n",
    "\n",
    "ttl = plt.title('SNR vs Accuracy', fontsize=16)\n",
    "ttl.set_weight('bold')\n",
    "plt.xlabel('SNR (dB)', fontsize=14)\n",
    "plt.ylabel('Test accuracy', fontsize=14)\n",
    "plt.grid()\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l2.2\n",
      "Confusion Matrix\n",
      "       8PSK  BPSK  CPFSK  GFSK  PAM4  QAM16  QAM64  QPSK\n",
      "8PSK   0.71  0.00   0.00  0.00  0.00   0.09   0.06  0.14\n",
      "BPSK   0.00  0.98   0.00  0.00  0.01   0.00   0.00  0.01\n",
      "CPFSK  0.02  0.00   0.96  0.00  0.00   0.00   0.00  0.01\n",
      "GFSK   0.01  0.00   0.01  0.97  0.00   0.00   0.00  0.00\n",
      "PAM4   0.00  0.01   0.00  0.00  0.98   0.01   0.00  0.00\n",
      "QAM16  0.02  0.00   0.00  0.00  0.00   0.44   0.54  0.00\n",
      "QAM64  0.01  0.00   0.00  0.00  0.00   0.48   0.51  0.00\n",
      "QPSK   0.13  0.01   0.00  0.00  0.00   0.03   0.01  0.82\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fa2953a1fd0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Confusion Matrix\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    saver.restore(sess, path)\n",
    "    Z = logits.eval(feed_dict = {X : X_test[18]})\n",
    "    predicted_18dB = np.argmax(Z, axis = 1)\n",
    "    \n",
    "from sklearn.metrics import confusion_matrix\n",
    "%matplotlib inline\n",
    "\n",
    "classes = ['8PSK', 'BPSK', 'CPFSK', 'GFSK', 'PAM4', 'QAM16', 'QAM64', 'QPSK']\n",
    "conf_matrix = confusion_matrix(predicted_18dB, y_test[18])  \n",
    "\n",
    "conf_matrix = conf_matrix.astype('float') / conf_matrix.sum(axis=1)[:, np.newaxis]\n",
    "conf_matrix = conf_matrix.round(decimals = 2)\n",
    "\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame(data = conf_matrix, columns = classes, index = classes) \n",
    "print(\"Confusion Matrix\")\n",
    "print(df)\n",
    "\n",
    "fig1 = plt.figure(figsize=(10, 6), dpi=100)\n",
    "plt.imshow(conf_matrix, interpolation = 'nearest', cmap = plt.cm.Purples)\n",
    "ticks = np.arange(len(classes))\n",
    "plt.title(\"Confusion Matrix\")\n",
    "plt.xticks(ticks, classes, rotation=45)\n",
    "plt.yticks(ticks, classes)\n",
    "\n",
    "plt.ylabel('True class')\n",
    "plt.xlabel('Predicted class')\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.colorbar()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  },
  "widgets": {
   "state": {},
   "version": "1.1.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
